package Zookeeper;

/**
 * 集群为啥最少为三台？
 * 因为集群的目的是为了   挂了一台服务器还能继续运行
 * 在集群设置的时候    会设置一共多少台服务器   集群的Leader必须在 半数以上
 * 1台  挂了就没了
 * 2台  挂了一台   由于服务器必须有半数以上才有主服务器
 *      2/2=1  挂了一台  他自己给自己投一票  咋样都不可以>1
 * 3台  挂了一台   由于服务器必须有半数以上才有主服务器
 *     3/2=1.5  挂了一台  一共有两票 >1.5  所以挂了一台   还存在集群
 */
public class 选举机制 {
}
/**
 * 第一次启动
 * （1）服务器1启动，发起一次选举。服务器1投自己一票。
 *      此时服务器1票数一票，不够半数以上（3票），
 *      选举无法完成，服务器1状态保持为LOOKING；
 * （2）服务器2启动，再发起一次选举。服务器1和2分别投自己一票并交换选票信息：
 *      此时服务器1发现服务器2的myid比自己目前投票推举的（服务器1）大，更改选票为推举服务器2。
 *      此时服务器1票数0票，服务器2票数2票，没有半数以上结果，选举无法完成，服务器1，2状态保持LOOKING
 * （3）服务器3启动，发起一次选举。此时服务器1和2都会更改选票为服务器3。
 *      此次投票结果：服务器1为0票，服务器2为0票，服务器3为3票。
 *      此时服务器3的票数已经超过半数，服务器3当选Leader。
 *      服务器1，2更改状态为FOLLOWING，服务器3更改状态为LEADING；
 * （4）服务器4启动，发起一次选举。此时服务器1，2，3已经不是LOOKING状态，不会更改选票信息。
 *     交换选票信息结果：服务器3为3票，服务器4为1票。此时服务器4服从多数，更改选票信息为服务器3，
 *     并更改状态为FOLLOWING；
 * （5）服务器5启动，同4一样当小弟。
 *
 *
 * SID：服务器ID。用来唯一标识一台ZooKeeper集群中的机器，每台机器不能重复，和myid一致。
 * ZXID：事务ID。ZXID是一个事务ID，用来标识一次服务器状态的变更。
 *      在某一时刻集群中的每台机器的ZXID值不一定完全一致，
 *      这和ZooKeeper服务器对于客户端“更新请求”的处理逻辑有关。
 * Epoch：每个Leader任期的代号。没有Leader时同一轮投票过程中的逻辑时钟值是相同的。
 *      每投完一次票这个数据就会增加
 *
 */

/**
 * 之后
 * 1.当ZooKeeper集群中的一台服务器出现以下两种情况之一时，就会开始进入Leader选举
 *      • 服务器初始化启动。
 *      • 服务器运行期间无法和Leader保持连接。
 * （2）而当一台机器进入Leader选举流程时，当前集群也可能会处于以下两种状态：
 *      • 集群中本来就已经存在一个Leader。
 *          对于第一种已经存在Leader的情况，机器试图去选举Leader时，
 *          会被告知当前服务器的Leader信息，对于该机器来说，
 *          仅仅需要和Leader机器建立连接，并进行状态同步即可。
 *      • 集群中确实不存在Leader。
 *          假设ZooKeeper由"5台"服务器组成，
 *          SID分别为1、2、3、4、5，
 *          ZXID分别为8、8、8、7、7，
 *          并且此时SID为3的服务器是Leader。
 *          某一时刻，3和5服务器出现故障，因此开始进行Leader选举。
 *                        （EPOCH，ZXID，SID ）（EPOCH，ZXID，SID ） （EPOCH，ZXID，SID ）
 * SID为1、2、4的机器投票情况： （1，8，1）         （1，8，2）             （1，7，4）
 *
 * 选举Leader规则： ①EPOCH大的直接胜出 ②EPOCH相同，事务id大的胜出 ③事务id相同，服务器id大的胜出
 *
 */
